home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 May / EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso / softwareupdate / system / amigados / parsingcommandline / parsingcommandline.doc < prev    next >
Text File  |  1996-10-10  |  42KB  |  1,140 lines

  1. 5    PARSING THE COMMAND LINE
  2.  
  3. 5.1  INTRODUCTION
  4.  
  5. When you are using the Shell (CLI) to launch programs you
  6. can add arguments after the program name. These arguments will
  7. be collected by the program and interpreted. In C you normally
  8. use the famous "argc" and "argv" variables.
  9.  
  10. Previously you had to write your own functions which
  11. interpreted the command line. Since every programmer wrote his
  12. or her own command line interpretator, or "parser" as they are
  13. also called, each program used its own routines to parse the
  14. arguments. The user was confronted with hundreds of different
  15. methods on how to enter the arguments, and this was very
  16. confusing for the user.
  17.  
  18. With Release 2 some special command line parsing routines were
  19. therefore included in the dos library. These routines take care
  20. of all the trouble with collecting arguments and interpreting
  21. them. As a programmer you will therefore save a lot of time
  22. since do not have to write your own parsing routines any more.
  23. These new routines will now also give the programs a
  24. standardized user-interface.
  25.  
  26. If you need to collect arguments from the command line you
  27. should use theses new routines in the dos library. You will
  28. save development time and get programs which follows the new
  29. standards. Both you and your users will benefit from it.
  30.  
  31. Plese note that these routines described in this chapter deals
  32. with parsing arguments from the command line (from the Shell,
  33. CLI). If you also want your programs to understand arguments
  34. from the Workbench you must also include the special routines
  35. described in the "Workbench" manual.
  36.  
  37.  
  38.  
  39. 5.2  COMMAND LINE INFORMATION
  40.  
  41. Not long ago all type of work with the computers was done by
  42. typing the commands and instructions. Nowadays the user can
  43. work a mouse, a light pen, or even directly talk to the
  44. computer (even if this voice control system still needs to be
  45. developed quite a bit before it will be practical). However,
  46. although there are a lot of new methods of collecting input
  47. from the user, the old trusted command line is still very
  48. much used. It maybe take some time to learn how to work with
  49. it, but the command line gives you a flexibility which can not
  50. be matched.
  51.  
  52. On the Amiga the users work in the "Workbench" enviroment, and
  53. can do most things by simply pointing and clicking with the
  54. mouse. However, since there are a lot of users, including me,
  55. who still now and then want to use the more flexible command
  56. line enviroment there exist the "Shell" or the simpler "CLI".
  57.  
  58.  
  59.  
  60. 5.2.1  PROGRAMS & ARGUMENTS
  61.  
  62. The advantage with the Shell and CLI is that it is very easy to
  63. give programs extra information when you start them. You simply
  64. write the name of the program and on the same line include one
  65. or more "arguments". To delete a file you normally use the
  66. program "Delete". The program must of course be told which
  67. file(s) to delete, and you give the program this information by
  68. adding one or more "arguments" as illustrated below: (See
  69. also picture "Programs&Arguments.pic")
  70.  
  71.   1.Prog:>
  72.   1.Prog:> Delete df0:ReadMe.doc df0:Unimportant.dat
  73.  
  74. The program is called "Delete", and the arguments are
  75. "df0:ReadMe.doc" and "df0:Unimportant.dat".
  76.  
  77.  
  78.  
  79. 5.2.2  COMMAND LINE TEMPLATE
  80.  
  81. Some programs can only handle one argument while others can
  82. handle several ones. The "Delete program" we discussed could
  83. for example handle several file names, while a drawing program
  84. maybe only can read one picture file. Some programs expect a
  85. "keyword" before the actual argument. When you for example want
  86. to format a disk you need to include the keywords "Drive" and
  87. "Name":
  88.  
  89.   1.Prog:>
  90.   1.Prog:> Format Drive df0: Name CPrograms
  91.  
  92. Other programs are using "switches" which means that something
  93. will be "turned on or off" if a special argumen is given. When
  94. you use the Delete command you can for example add the switch
  95. "Quiet" which tells the program not to list the files which are
  96. deleted:
  97.  
  98.   1.Prog:>
  99.   1.Prog:> Delete df0:System Quiet
  100.  
  101. Some arguments may be always required, you must for example
  102. give the Delete program at least one filename. Other arguments
  103. are optional like the "Quiet" switch.
  104.  
  105. As you understand the routines of handling arguments (the
  106. "parsing" routines) are very complex. The problem is that
  107. this complex enviroment must be made as simple as possible to
  108. use. Although every program uses different types of arguemnts
  109. and all have different requirements the parsing routines must
  110. be standardlized. The good news is that the new functions in
  111. the dos library gives us this.
  112.  
  113. The parsing routines are using what may be called a "Command
  114. Line Template". It is a text string in which the possible
  115. arguments, their requirements and function are incuded. Every
  116. unique argument type use a "Command Template". In the command
  117. template you enter the name of the argument and adds any
  118. necessary "options" which will be listed later on. These
  119. special options tells the parsing routine what type of argument
  120. should be expected, and what function it has.
  121.  
  122. This command line template is used by the parsing routines, but
  123. can also be viewed by the user. If you enter the name of the
  124. program and adds a question mark as the only argument you will
  125. see the complete command line template. To see the command line
  126. template used by the Delete program simply type "Delete ?":
  127.  
  128.   1.Prog:>
  129.   1.Prog:> Delete ?
  130.   FILE/M/A,ALL/S,QUIET/S,FORCE/S
  131.  
  132. The Delete program needs at least one argument which is the
  133. name of the file that should be deleted. In the "command
  134. template" the argument type is called "File". You can call
  135. the command templates almost anything you like, but you should
  136. notice that the user can look at the command line template by
  137. adding a question mark just after the program name (you can
  138. turn off this feature if you like but it is not recommended),
  139. and the name should somehow give the user a hint of what is
  140. expected.
  141.  
  142. Since the "File" argument was needed or else the program would
  143. fail a special "/A" option is added after the template name.
  144. This option tells the parsing routines that this argument is
  145. "Always Required". If the user does not enter an argument which
  146. is always required the parsing routine will fail. Since the
  147. user may enter several file names this command template also
  148. have the option "/M" set. The "/M" option tells the parsing
  149. routines that this is a "Multiple Argument", and one or more
  150. arguments of this type should be expected. The complete command
  151. template for the "File" argument of the "Delete" program is:
  152.  
  153.   "FILE/M/A"
  154.  
  155. (The template is called "File", one or more arguments of this
  156. type should be expected, and at least one argument of this type
  157. must be entered.)
  158.  
  159. The file name(s) was not the only type of argument the Delete
  160. program understands. You can also add the switch "Quiet". This
  161. argument type is, as previously explained, a switch which will
  162. be turned on if the argument is included, and be off if it is
  163. not included. To tell the parsing routines that the command
  164. template is a switch you add the "/S" option ("Switch"). The
  165. name of this command template is not surprisingly "QUIET", and
  166. the whole command template is therefore:
  167.  
  168.   "QUIET/S"
  169.   
  170. There are two more types of arguments that can be added,
  171. "Force" and "All", and they are also switches so I will not
  172. explain them further.
  173.  
  174. Each command template must be separated with a comma, and no
  175. spaces are allowed. (However, when the user should run the
  176. program and enters the argument he/she should separate the
  177. arguments with spaces and not use commas).
  178.  
  179. The parsing routines are not case sensetive which means that
  180. you can write "qUiEt" as well as "QUIET".
  181.  
  182. The complete "Command Line Template" for the Delete program
  183. will therefore look like this: (Please notice the destinction
  184. between "Command Template" which is the definitions of one
  185. argument type, and the "Command Line Template" which is the
  186. name of all the "Command Templates".)
  187.  
  188.   "FILE/M/A,ALL/S,QUIET/S,FORCE/S"
  189.  
  190. This types of command line template can be used with the parse
  191. functions. The advantage with this "string" form is that it can
  192. by used by the parsing routines, but still be displayed for the
  193. user and he/she will then know what must be typed and which
  194. features are available.
  195.  
  196.  
  197.  
  198. 5.2.3  TEMPLATE OPTIONS
  199.  
  200. Here is the complete list of all avilable options you may add
  201. to the command template. You may use several options for each
  202. command template. Simply add them together after the name.
  203. (To add both the "/A" and "/M" option simply add the string
  204. "/A/M" at the end of the command template name.)
  205.  
  206.   Option  Description
  207.   -------------------------------------------------------------
  208.       /A  Always required argument. This argument must always
  209.           be included in the command line, or else the parse
  210.           function will fail.
  211.  
  212.       /F  Final argument of the line. All text after this
  213.           argument will be considered as a part of the argument
  214.           nomatter what is written.
  215.           
  216.       /K  Keyword is required. The user must include the name
  217.           of the command template before he/she type the actual
  218.           argument. The user may add an equal sign between the
  219.           "keyword" (the name of this command template) and the
  220.           actual argument.
  221.  
  222.           Example. If your program has the following command
  223.           template, "NAME/K", the user must write:
  224.  
  225.             NAME <the actual argument>   or
  226.             NAME=<the actual argument>
  227.  
  228.       /M  Multiple arguments may be entered. The user may write
  229.           more than one argument of this type. If this option
  230.           is not used the user may only enter one argument of
  231.           this type. If the option is on the user may enter one
  232.           or more arguments. (The user may of course enter no
  233.           argument at all of this type as long as the "/A"
  234.           option is not included as well in the command
  235.           template.)
  236.  
  237.           The advantage with this option is that all arguments
  238.           that could not fit in anywhere else will be added to
  239.           this command template. For example: the Delete
  240.           program has the following command line template:
  241.          
  242.             "FILE/M/A,ALL/S,QUIET/S,FORCE/S"
  243.  
  244.           As you can see, the user may enter as many file names
  245.           as he/she wants since the "/M" option is set. (At
  246.           least one file name must be given since the "/A"
  247.           option is set.) To delete the the files f1, f2 and f3
  248.           and do it quietly you may write:
  249.           
  250.             Delete f1 f2 f3 Quiet
  251.  
  252.           You can also write:
  253.  
  254.             Delete f1 Quiet f2 f3
  255.  
  256.           Since the arguments f2 and f3 did not fit any other
  257.           template (were not "All", "Quiet" or "Force") they
  258.           will be added to the "FILE" template.
  259.  
  260.           Note! Only one "/M" option may be used on a command
  261.           line template. (It would otherwise be impossible for
  262.           the parse functions to know to which commad template
  263.           the extra arguments should go to if there were
  264.           several "/M" options.)
  265.  
  266.       /N  Number argument. If the user enters this argument it
  267.           must be an integer value (a value with no period).
  268.           The value may be negative.
  269.  
  270.       /S  Switch argument. This option should be used if you
  271.           want the command template to act like a switch. If
  272.           his argument is entered it will be turned on, else
  273.           it will be turned off.      
  274.  
  275.       /T  Toggle argument. This option should be used if you
  276.           want the command template to act like a switch that
  277.           is toggled on and of. If this argument is enterd the
  278.           switch will be toggled (if it was off it will be
  279.           turned on, and if it was on it will be turned off).
  280.  
  281.  
  282.  
  283. 5.2.4  ABBREVIATIONS
  284.  
  285. You should always use complete words as a name for a command
  286. template since it will be easier for the user (and for you as
  287. a programmer also) to understand and remember what that
  288. argument type is about. However, to save time you can allow
  289. the user to enter abreviations. If you have the command
  290. template name "Rate" you might want allow the abreviation
  291. "R" as well. To do this you simply add "R=" at the begining
  292. of the name: "R=Rate".
  293.  
  294.  
  295.  
  296. 5.2.6  RESERVED NAMES
  297.  
  298. There are some command template names that are "reserved". You
  299. may only use these names if your command templates mean the
  300. same thing as the reserved names. This will give the user a
  301. more standardized interface. ("Commodore Amiga Technical
  302. Information")
  303.  
  304.   Name       Purpose
  305.   -------------------------------------------------------------
  306.   FILE         The argument should be the name of the file that
  307.                the program should use. (One file.)
  308.  
  309.   FILES/M      The arguments should be the name of the files
  310.                that the program should use. (One or more files,
  311.                note the "/M" multiple arguments option.)
  312.  
  313.   NOGUI/S      This argument should be used as a switch to turn
  314.                off the graphics interface (GUI = "Graphics User
  315.                Interface"). This can for example be handy if
  316.                the user want to save memory, and does not want
  317.                fancy gadgets with a lot of nice but memory
  318.                hungry graphics. As little graphics as possible
  319.                should be used if your program receives this
  320.                argument. (Mouse operations ar usually
  321.                considered to be a part of the GUI, but if you
  322.                want to turn of the mouse completely or simply
  323.                remove fancy graphics is up to you.)
  324.  
  325.   PORTNAME/K   This argument should be the name of the ARexx
  326.                port that will be used. Note that the keyword
  327.                "PORTNAME" must preceded the name of the
  328.                ARexx port (the "/K" keyword option is used.)
  329.  
  330.   PUBSCREEN/K  This argument should be the name of the public
  331.                screen this application should use. Note that
  332.                the keyword "PUBSCREEN" must preceded the name
  333.                of the public screen.
  334.  
  335.   SETTINGS/K   This argument should be the name of the
  336.                preferences file that will be loaded when the
  337.                program is started. Note that the keyword
  338.                "SETTINGS" must preceded the file name.
  339.  
  340.   STARTUP/K    This argument should be the name of the ARexx
  341.                program that will be executed when this program
  342.                is started. Note that the keyword "STARTUP" must
  343.                preceded the name of the ARexx file.
  344.   
  345.   
  346.  
  347. 5.2.7  SOME EXAMPLES
  348.  
  349. For a summary of the different parts of the command line
  350. template see picture "CommandLineTemplate.pic".
  351.  
  352. I will now show some examples on different types of command
  353. templates. I will also show some command lines that the user
  354. may and may not use. (I assume that the program name is
  355. "MyProg".)
  356.  
  357. Template: "FILE"
  358.  
  359.   Command line                   Comments
  360.   -------------------------------------------------------------
  361.   MyProg                         OK! The file name was optional
  362.                                  since the "/A" option was not
  363.                                  used.
  364.  
  365.   MyProg Bird.snd                OK! One file name may be
  366.                                  entered.
  367.  
  368.   MyProg Bird.snd Sea.snd        WRONG! Only one file name may
  369.                                  be entered since the "/M"
  370.                                  option was not used.
  371.  
  372.  
  373. Template: "FILES/M"
  374.  
  375.   Command line                   Comments
  376.   -------------------------------------------------------------
  377.   MyProg                         OK! The file name was optional
  378.                                  since the "/A" option was not
  379.                                  used.
  380.  
  381.   MyProg Bird.snd                OK! One file name may be
  382.                                  entered even if the "/M"
  383.                                  option is used.
  384.  
  385.   MyProg Bird.snd Sea.snd        OK! Several file names may
  386.                                  be entered since the "/M"
  387.                                  option was used.
  388.  
  389.  
  390. Template: "FILE/A"
  391.  
  392.   Command line                   Comments
  393.   -------------------------------------------------------------
  394.   MyProg                         WRONG! A file name is required
  395.                                  since the "/A" option was
  396.                                  used.
  397.  
  398.   MyProg Bird.snd                OK! One file name should be
  399.                                  entered.
  400.  
  401.   MyProg Bird.snd Sea.snd        WRONG! Only one file name may
  402.                                  be entered since the "/M"
  403.                                  option was not used.
  404.  
  405.  
  406. Template: "VOLUME/N"
  407.  
  408.   Command line                   Comments
  409.   -------------------------------------------------------------
  410.   MyProg                         OK! The volume number was
  411.                                  optional since the "/A" option
  412.                                  was not used.
  413.  
  414.   MyProg 30                      OK! The volume may be set as
  415.                                  long as it is an integer
  416.                                  value (without any period).
  417.  
  418.   MyProg 30.25                   WRONG! Only integer values may
  419.                                  be entered!
  420.  
  421.   MyProg Bird.snd                WRONG! It must be an integer
  422.                                  number since the "/N" option
  423.                                  was used.
  424.  
  425.  
  426. Template: "VOLUME/N/K"
  427.  
  428.   Command line                   Comments
  429.   -------------------------------------------------------------
  430.   MyProg 30                      WRONG! The number must be
  431.                                  preceded by the keyword
  432.                                  "VOLUME" since the "/K" option
  433.                                  was used.
  434.  
  435.   MyProg Volume 30               OK! The keyword, as well as
  436.                                  all other arguments, are not
  437.                                  case sensetive.
  438.  
  439.   MyProg Volume=30               OK! You may use an equal sign
  440.                                  between the keyword and the
  441.                                  actual argument instead of a
  442.                                  space.
  443.  
  444.  
  445. Template: "F=FILTER/S"
  446.  
  447.   Command line                   Comments
  448.   -------------------------------------------------------------
  449.   MyProg Filter                  OK! The switch "FILTER" will
  450.                                  be turned on.
  451.  
  452.   MyProg F                       OK! The switch "FILTER" may be
  453.                                  abbreviated to "F" since we
  454.                                  added the "F=" string.
  455.                                  ["<Abbreviation>="]
  456.  
  457.  
  458. Template: "FILES/A/M,V=VOLUME/N/K,F=FILTER/S"
  459.  
  460.   Command line                   Comments
  461.   -------------------------------------------------------------
  462.   MyProg Bird.snd Volume=30      OK!
  463.  
  464.   MyProg Volume=30 Bird.snd      OK! The order of the arguments
  465.                                  is irrelevant.
  466.  
  467.   MyProg Volume=30 Filter        WRONG! A file name is required
  468.                                  since the "/A" option was
  469.                                  used.
  470.  
  471.   MyProg Bird.snd Sea.snd V=30 F OK! Several file names may be
  472.                                  used since the "/M" option was
  473.                                  used, and the "VOLUME" and
  474.                                  "FILTER" words may be
  475.                                  abbreviated to "V" and "F".
  476.  
  477.  
  478.  
  479. 5.3  PARSE THE COMMAND LINE
  480.  
  481. When you want to parse the command line (collect arguments from
  482. the command line you simply have to follow these six steps:
  483.  
  484.   1. Check the dos library version.
  485.   2. Design the command line template.
  486.   3. Prepare the "argument array".
  487.   4. Collect the arguments.
  488.   5. Examine the result and act accordingly.
  489.   6. Finally you should clean up after you.
  490.  
  491.  
  492.  
  493. 5.3.1  CHECK DOS LIBRARY VERSION
  494.  
  495. The parsing functions were introduced with Release 2. The first
  496. version of the new dos library (V36) was rather buggy, and the 
  497. parsing routines did not work correctly. Before you may use any
  498. of the parsing functions you must therefore make sure that the
  499. user really has dos library version 37 or higher.
  500.  
  501. How to check the current dos library version was explained in
  502. the first chapter "AmigaDOS". However, here is a short example:
  503.  
  504.   /* Declare an external global library */
  505.   /* pointer to the Dos library:        */
  506.   extern struct DosLibrary *DOSBase;
  507.  
  508.   - - -
  509.  
  510.   /* We need dos library version 37 or higher: */
  511.   if( DOSBase->dl_lib.lib_Version < 37 )
  512.   {
  513.     /* Too old dos library! */
  514.     printf( "This program needs Dos Library V37 or higher!\n" );
  515.    
  516.     /* Exit with an error code: */ 
  517.     exit( 20 );
  518.   }
  519.  
  520.  
  521.  
  522. 5.3.2  DESIGN THE COMMAND LINE TEMPLATE
  523.  
  524. The parsing functions are using a command line template, which
  525. is simply a string where you include all your requirements as
  526. previously explained.
  527.  
  528. When you set the command template names you should give them
  529. complete names which are easy to understand and can not be
  530. mixed up. If you want to can give the user an option of
  531. abbreviate long names. 
  532.  
  533. Any arguments that are necessary for your program to work must
  534. have the "/A" option set, and if your program supports multiple
  535. arguments of one type you must set the "/M" option for that
  536. command template. Please remember that only one "\M" option can
  537. be used in the command template.
  538.  
  539. It is important that you design the command line template
  540. carefully, and make sure that the parsing functions really
  541. can handle it. If you use several command templates in the
  542. command line template you must be careful so that the parsing
  543. routine can separate the arguments correctly:
  544.  
  545.   * There is no danger with "switches" (option "/S" anb /T")
  546.     since the parsing routines will automatically know which
  547.     argument belongs to which command template. For example:
  548.     the command line template "MONO/S,FILTER/S" is easy to
  549.     handle. If the user enters the argument "Mono" it can
  550.     only be the "MONO" switch.
  551.  
  552.   * When you are using the other types of arguments you must
  553.     design the command line template so the different
  554.     arguments can be separated, and there is no risk of mixing
  555.     them up. To do this you normally need to use the "keyword"
  556.     option (option "/K").
  557.     
  558.     For example: We have a small program that loads a sound
  559.     file and a picture file. A command line template like
  560.     "SOUND,PICTURE" should however not be used! It is
  561.     imposible to know which argument is the name of the sound
  562.     file and which is the name of the picture. The user maybe
  563.     writes:
  564.  
  565.       MyProg Bird.snd Fun.pic
  566.      
  567.     However, the user might equally well write:
  568.      
  569.       MyProg Fun.pic Bird.snd 
  570.        
  571.     As you see, the user has changed the order of the
  572.     arguments, and it would be impossible for the parsing
  573.     functions to know that the first argument "Fun.pic"
  574.     actually is the picture file, and that the second argument
  575.     "Bird.snd" is the sound file. (The order of the arguments
  576.     on the command line should not matter, so do not expect 
  577.     the first argument to be the sound file and the second one
  578.     the picture file.)
  579.     
  580.     What you should do is to add a keyword for at least one of
  581.     the command templates. Possible examples:
  582.  
  583.       "SOUND/K,PICTURE"   The user must now enter the keyword
  584.                           "SOUND" before the actual file name.
  585.                           There will then not be any
  586.                           uncertainty of which argument is
  587.                           which.
  588.  
  589.       "SOUND/K,PICTURE/K" Same as above except that the user
  590.                           now must enter the keyword "PICTURE"
  591.                           just before the actual picture name.
  592.                           
  593.       "SOUND/K,PICTURE/K" The user must now enter the keywords
  594.                           "SOUND" in front of the sound file,
  595.                           and "PICTURE" in front of the
  596.                           picture name.
  597.  
  598. Here is a typical example on how to decalre a command line
  599. templat:
  600.  
  601.   /* Here is our command line template: */
  602.   #define MY_TEMPLATE "SoundFile/A,V=Volume/K/N,F=Filter/S"
  603.  
  604.  
  605.  
  606. 5.3.3  PREPARE THE ARGUMENT ARRAY
  607.  
  608. After the command line has been parsed are collected data
  609. stored in an array of LONG variables. One entry (LONG variable)
  610. is needed for every command template.
  611.  
  612.   *******************************************************
  613.   *                                                     *
  614.   *  Remember! The array must contain at least as many  *
  615.   *  entries (LONG variables) as there are command      *
  616.   *  templates in your command line template!           *
  617.   *                                                     *
  618.   *******************************************************
  619.  
  620. It is important that this "argument" array has been cleared,
  621. all variables set to 0, before it is used. There is only one
  622. exception, and that is if you want to use the "toggle" ("/T")
  623. option, which will toggle the corresponding variable in the
  624. array. More about this later.
  625.  
  626. Here is an example: (Our command line template has three
  627. command templates, and consequently we need an array with at
  628. least three entries.)
  629.  
  630.   /* Three command templates are used: */
  631.   #define NUMBER_TEMPLATES 3
  632.  
  633.   /* The results of the parsing will be stored here: */
  634.   LONG arg_array[ NUMBER_TEMPLATES ];
  635.  
  636.   - - -
  637.  
  638.   /* We will now clear the array: */
  639.   for( loop = 0; loop < NUMBER_TEMPLATES; loop++ )
  640.     arg_array[ loop ] = 0;
  641.  
  642.  
  643.  
  644. 5.3.4  COLLECT THE ARGUMENTS
  645.  
  646. Once you have designed the command template and allocated
  647. (declared) an array of LONG variables you can parse the command
  648. line. To do this you simply call the ReadArgs() function.
  649.  
  650. The ReadArgs() function needs a pointer to the command line
  651. emplate that should be used and a pointer to the array of of
  652. LONG variables.
  653.  
  654. If the command line could successfully be parsed a pointer is
  655. returned to a RDArgs structure that has been allocated. If the
  656. command line could not be parsed NULL is returned. (The RDArgs
  657. structure will be explained later on in this chapter.)
  658.  
  659. Synopsis: retrda = ReadArgs( cltemplate, arg_array, rdargs );
  660.  
  661.   retrda:     (struct RDArgs *) The function returns a pointer
  662.               to a RDArgs structure if the command line could
  663.               successfully be parsed. If the command line could
  664.               not be parsed NULL is returned.
  665.               
  666.   cltemplate: (STRPTR) Pointer to a sting which contains our
  667.               command line template.
  668.  
  669.   arg_array:  (LONG *) Pointer to the argument array where the
  670.               results will be stored.
  671.  
  672.   rdargs:     (struct RDArgs *) If you want to set some special
  673.               flags or parse your own command string you should
  674.               give the function a pointer to your own RDArgs
  675.               structure, else set this field to NULL.
  676.  
  677. Here is an example:
  678.  
  679.   /* Declare a pointer to a RDArgs structure: */
  680.   struct RDArgs *my_rdargs;
  681.  
  682.   - - -
  683.  
  684.   /* Parse the command line: */
  685.   my_rdargs = ReadArgs( MY_TEMPLATE, arg_array, NULL );
  686.  
  687.   /* Any problems? */
  688.   if( !my_rdargs )
  689.   {
  690.     /* The command line could not be parsed! The user probably */
  691.     /* forgot to enter an argument which is required, or too   */
  692.     /* many arguments were given, or the arguemnts where       */
  693.     /* incorrect.                                              */
  694.     printf( "Could not parse the command line!\n" );
  695.  
  696.     /* Exit with an error code: */ 
  697.     exit( 20 );
  698.   }
  699.  
  700.  
  701.  
  702. 5.3.5  EXAMINE THE ARGUMENTS
  703.  
  704. Once you have successfully parsed the command line you may
  705. examine the "argument" array. The result of the first
  706. command template will be placed in position 0 of the array,
  707. the result of the second command template will be placed in
  708. position 1, and so on... 
  709.  
  710. What type of values that will be stored in the array depends on
  711. what type of command templates are used (which options that
  712. where set): (In all examples we assume that the argument type
  713. we work with has the position "POSITION" in the argument array.)
  714.               
  715. 1. The default is that the array will contain a pointer to a
  716.    string where a copy of the corresponding argument is placed.
  717.    If no argument of this type was entered the pointer will be
  718.    NULL.
  719.   
  720.    Remember to check that the pointer really points to a string
  721.    before you try to examine the string! If the "/A" option was
  722.    used together with this template we know that the pointer
  723.    must point to a string since this argument was required, and
  724.    the ReadArgs() function would have failed if this argument
  725.    was not included. However, it it best to always check the
  726.    pointer that it does not point to NULL before you use it!
  727.  
  728.    Here is an example on how to print a collected string
  729.    argument:
  730.  
  731.      /* Print single string argument: */
  732.      if( arg_array[ POSITION ] )
  733.        printf( "File name: %s\n", arg_array[ POSITION ] );
  734.  
  735.            
  736. 2. If the "/M" (multiple arguments) option was used there may
  737.    be zero or more arguments that fitted this template. The
  738.    LONG value in the array  will therefore contain a pointer to
  739.    an array of strings, where the last string pointer is set to
  740.    NULL. (Note that it is a pointer to an array of string
  741.    pointers.)
  742.  
  743.    Here is an example on how to print all of the collected
  744.    strings used with a multiple command template:
  745.  
  746.      /* Simple loop variable: */
  747.      int loop;
  748.  
  749.      /* Store the pointer to the array of string pointers here: */
  750.      UBYTE **string_array;
  751.  
  752.      - - -
  753.      
  754.      /* Before we can use the pointer we must check that  */
  755.      /* we realy have a pointer to other strings, and not */
  756.      /* just NULL.                                        */
  757.      if( arg_array[ POSITION ] )
  758.      {
  759.        /* Store the pointer to the array of stirng pointers: */
  760.        /* (Double pointers are a bit tricky...)              */
  761.        string_array = (UBYTE **) arg_array[ POSITION ];
  762.   
  763.        /* What we have to do now is to examine all strings  */
  764.        /* with help of a simple while loop. The last string */
  765.        /* in the array has been set to NULL so we know were */
  766.        /* the list ends.                                    */
  767.     
  768.        /* Start with the first string: */
  769.        loop = 0;
  770.  
  771.        /* Print all file names: */
  772.        while( string_array[ loop ] )
  773.        {
  774.          /* Print the file name: */
  775.          printf( "File name: %s\n", string_array[ loop ] );
  776.  
  777.          /* Increase the counter: */
  778.          loop++;
  779.        }
  780.        /* All file names have now been printed! */
  781.      }
  782.      else
  783.        printf( "Not a single file name...\n" );
  784.  
  785.  
  786. 3. If the "/N" (numeric argument) option was used the LONG
  787.    variable in the array will contain a pointer to the value
  788.    that was entered, or be NULL if no value was entered.
  789.  
  790.    Here is an example on how to print a collected value:
  791.    
  792.      /* A pointer to the volume value: */
  793.      LONG *value;
  794.  
  795.      - - -
  796.  
  797.      /* Check that the user really has entered a number: */
  798.      if( arg_array[ POSITION ] )
  799.      {
  800.        /* Get a pointer to the value: */
  801.        value = (LONG *) arg_array[ POSITION ];
  802.  
  803.        /* Print the value: */
  804.        printf( "The value is: %ld\n", *value );
  805.      }
  806.      else
  807.        printf( "No value was entered!\n" );
  808.  
  809.  
  810. 4. Finally there exist the switches "/S" (or "flags" as they
  811.    are sometimes called). If the switch was set the variable in
  812.    the array will be non-zero. If the switch was not set the
  813.    value will be 0.
  814.    
  815.    If you used the "/T" switch the value in the array will
  816.    toggle if the argument was set. If the value in the array
  817.    was 0 it will be toggled to a non-zero value, and if the
  818.    value was non-zero it will be togled to 0. The argument
  819.    array should normally always be set to zero before you
  820.    collect the arguments. The variable used for a toggle
  821.    switch may however be set to ~0 if you want it to have a
  822.    non-zero value before you collect the arguments. (The toggle
  823.    option is normally only used when you parse your own command
  824.    strings. The command line is only entered once and a toggle
  825.    option would not be of much use here.)
  826.  
  827.    Here is an example to check if a switch (flag) was set or
  828.    not:
  829.  
  830.      /* Was the switch set? */
  831.      if( arg_array[ POSITION ] )
  832.         printf( "The switch (flag) was set!\n" );
  833.      else
  834.        printf( "The switch (flag) was not set!\n" );
  835.  
  836.  
  837.  
  838. 5.3.6  CLEAN UP
  839.  
  840. When you successfully call ReadArgs() the function will
  841. allocate some memory where the collected arguments will be
  842. stored. It is this memory the pointers in the argument array
  843. points to. Once you have examined the collected arguments and
  844. do not need them any more you should free the data. You do this
  845. by simply calling the FreeArgs() function.
  846.  
  847. If you did not supply the ReadArgs() function with your own
  848. RDArgs structure the function will have created one for you.
  849. This structure will then also be deallocated when you call
  850. FreeArgs().
  851.  
  852. If you have created your own RDArgs structure you have to
  853. deallocate it yourself with help of FreeDosObject(). However,
  854. you must still call FreeArgs() to deallocate the data used for
  855. the arguments.
  856.  
  857. Synopsis: FreeArgs( retrda );
  858.  
  859.   retrda: (struct RDArgs *) Pointer to the RDArgs structure
  860.           that was returned when you called ReadArgs().
  861.  
  862. Please note that the memory area where the collect arguments
  863. were stored will not exist any more after you have called
  864. FreeArgs(). You must therefore, of course, never try to access
  865. the data agian after you have deallocated it.
  866.  
  867. Here is an example on how to free the data that have previously
  868. been allocated when you called ReadArgs():
  869.  
  870.   /* Free the arguments: */
  871.   FreeArgs( my_rdargs );
  872.  
  873.  
  874.  
  875. 5.4  ADVANCED PARSING ROUTINES
  876.  
  877. As you saw most of the parsing job was done automatically for
  878. you. It collected the command line, parsed it automatically
  879. (you only had to tell it which arguments to look for), and
  880. finally the parsing routine inserted all the sorted arguments
  881. into your array. Handy and easy to use.
  882.  
  883. However, you might want to have more control over the parsing
  884. routine, add some extra help or parse your own strings rather
  885. than the default command line etc... This is also possible,
  886. and will be explained in the following sections.
  887.  
  888.  
  889.  
  890. 5.4.1  RDARGS AND CSOURCE STRUCTURES
  891.  
  892. Before I start to explain the different options you may use
  893. and how you can control the parsing routines, I will explain
  894. two structures, CSource and RDArgs, you will have to use:
  895.  
  896. The CSource structure looks like this: (defined in header file
  897. "dos/rdargs.h")
  898.  
  899.   struct CSource
  900.   {
  901.     UBYTE *CS_Buffer;
  902.     LONG CS_Length;
  903.     LONG CS_CurChr;
  904.   } 
  905.  
  906. CS_Buffer: Pointer to some memory where a string may be stored.
  907.  
  908. CS_Length: The lenght of the string.
  909.  
  910. CS_CurChr: The current "position" in the string. This field is
  911.            normally used by the parsing routines to keep track
  912.            of where they are for the moment in the string they
  913.            are examening. Normally this field should be set to
  914.            zero.
  915.  
  916. The RDArgs structure looks like this: (defined in header file
  917. "dos/rdargs.h")
  918.  
  919.   struct RDArgs
  920.   {
  921.     struct CSource RDA_Source;
  922.     LONG RDA_DAList;
  923.     UBYTE *RDA_Buffer;
  924.     LONG RDA_BufSiz;
  925.     UBYTE *RDA_ExtHelp;
  926.     LONG RDA_Flags;
  927.   };
  928.  
  929. RDA_Source:  The first object is a CSource structure. It is
  930.              in this structure you can set your own command
  931.              string which will be parsed instead of the the
  932.              defult command line. (If the fields in this
  933.              structure is set to NULL the defautl command
  934.              line will be parsed.)
  935.  
  936. RDA_DAList:  Private area, used by AmigaDOS only. Set to NULL.
  937.  
  938. RDA_Buffer:  Normally when you use ReadArgs() some memory will
  939.              be automatically allocated to store the arguments
  940.              in. (It is this memory which you then have to free
  941.              with help of FreeArgs().) If you want ReadArgs()
  942.              to take care of all memory handeling you should
  943.              set this field to NULL and the next one
  944.              ("RDA_BufSiz") to zero.
  945.              
  946.              However, sometimes you might want to allocate
  947.              the memory yourself before you call the ReadArgs()
  948.              function. What you have to do is to allocate some
  949.              mempory and give this field a pointer to that
  950.              memory. You must then also tell this structure
  951.              how much memory you have allocated, and this you
  952.              do in the next field ("RDA_BufSiz").
  953.  
  954.              Note! If you have allocated the memory yourself
  955.              for this field you should not call FreeArgs()
  956.              but instead deallocate the memory yourself.
  957.  
  958. RDA_BufSiz:  Normally set to 0, but if you have allocated the
  959.              memory yourself as described above you must set
  960.              the size (in bytes) here.
  961.              
  962. RDA_ExtHelp: If you want you can give this field a pointer to
  963.              a string which will be used as an "extra" help
  964.              line. If the user types a question mark he/she
  965.              will see the command line template. If the user
  966.              now types another question mark he/she will see
  967.              this string.
  968.  
  969. RDA_Flags:   In this field you can set special flags which will
  970.              in different ways affect the parsing routines. For
  971.              the mement you can only use the "RDAF_NOPROMPT"
  972.              flag. It will turn off the command line template
  973.              so the user can not see it if he/she types a
  974.              question mark (?).
  975.  
  976.  
  977. To allocate a RDArgs structure you must use the special
  978. AllocDosObject() function. The advantage with using this
  979. function is that any future changes in the size of the RDArgs
  980. strucute will not affect the compability of your program. For
  981. example, if the strucute is extended the AllocDosObject() will
  982. automatically allocate more memory. The function will also
  983. initialize some fields of the structure so it can be used
  984. directly. 
  985.  
  986. Synopsis: object = AllocDosObject( type, tags );
  987.  
  988.   object: (APTR) The function will return a pointer to the
  989.           allocated object, or NULL if there was an error.
  990.           In our case a pointer to a RDArgs structure will
  991.           be returned on NULL.
  992.  
  993.   type:   (ULONG) The type of object you want to allocate.
  994.           You can find the complete list in header file
  995.           "dos/dos.h". Since we want a RDArgs structure
  996.           we set this field to: "DOS_RDARGS"
  997.   
  998.   tags:   (struct TagItem *) In some situations you might want
  999.           to add some special requirements which you can do
  1000.           here. However, since we only want a simple RDArgs
  1001.           structure we set this filed to NULL.
  1002.  
  1003. If you have successfully created an RDArgs structure with help
  1004. of AllocDosObject() you also have to deallocate it yourself
  1005. when you do not need the structure any more. Anything which has
  1006. been allocated with AllocDosObject() must be deallocated with
  1007. help of the FreeDosObject() function.
  1008.  
  1009. Synopsis: FreeDosObject( type, object );
  1010.  
  1011.   type:   (ULONG) The type of object you want to deallocte. In
  1012.           our case we want to deallocate a RDArgs structure so
  1013.           we set the flag "DOS_RDARGS".
  1014.  
  1015.   object: (APTR) Pointer to the object you want to deallocate.
  1016.           In our case a pointer to the RDArgs structure.
  1017.  
  1018.  
  1019. Here is an example on how to create and later on free a RDArgs
  1020. structure:
  1021.  
  1022.   /* Declare a pointer to our RDArgs structure: */
  1023.   struct RDArgs *my_rdargs;
  1024.  
  1025.   - - -
  1026.  
  1027.   /* Allocate a RDArgs structure: */
  1028.   my_rdargs = (struct RDArgs *)
  1029.     AllocDosObject( DOS_RDARGS, NULL );
  1030.  
  1031.   /* Did we get the RDArgs structure? */
  1032.   if( !my_rdargs )
  1033.   {
  1034.     /* Problems! Inform the user: */
  1035.     printf( "Could not create the RDArgs structure!\n" );
  1036.  
  1037.     /* Quit with an error code: */
  1038.     exit( 20 );
  1039.   }
  1040.  
  1041.   - - - 
  1042.  
  1043.   /* Here you may use the RDArgs structure as will */
  1044.   /* be explained in the following sections.       */
  1045.  
  1046.   - - -
  1047.  
  1048.   /* Deallocate the RDArgs structure: */
  1049.   FreeDosObject( DOS_RDARGS, my_rdargs );
  1050.  
  1051.  
  1052.  
  1053. 5.4.2  TURN OFF THE COMMAND TEMPLATE LINE HELP
  1054.  
  1055. It is possible to turn off the command line template so the
  1056. user can not see it when he/she types a question mark. This
  1057. should not be done in most cases since the user may need this
  1058. help. However, you maybe want to print your own help messages
  1059. instead. (If you turn off this "autohelp" you will be able to
  1060. scan for question marks and if you find one you can print some
  1061. instructions for example.)
  1062.  
  1063. To turn off the command line template so the user can not see
  1064. it you need to set the flag "RDAF_NOPROMPT" in the "RDA_Flags"
  1065. field of the RDArgs structure before you call ReadArgs().
  1066.  
  1067. Here is a (very) simple example:
  1068.  
  1069.   /* Turn of the comman line template help: */
  1070.   my_rdargs->RDA_Flags = RDAF_NOPROMPT;
  1071.  
  1072.   /* Call ReadArgs() etc... */
  1073.  
  1074.  
  1075.  
  1076. 5.4.3  ADD EXTRA HELP LINE
  1077.  
  1078. If you want you can add an extra help line which will be
  1079. displayed if the user first types a question mark to see the
  1080. "command line template help" and then types another question
  1081. mark. The advantage with this extra help line is that you can
  1082. give the user some more understandable help. The command line
  1083. template is not the easiest thing to understand in the
  1084. beginning.
  1085.  
  1086. To set an extra help line simple give the "RDA_ExtHelp" field
  1087. of the RDArgs structure a pointer to a text string which
  1088. contains the text you want to display. (This must of course be
  1089. done before you call ReadArgs().)
  1090.  
  1091. Here is a simple example:
  1092.  
  1093.   /* Set an extra help line: */
  1094.   my_rdargs->RDA_ExtHelp = (UBYTE *)
  1095.     "You must enter a name of a sound file!";
  1096.  
  1097.  
  1098.  
  1099. 5.4.4  PARSE YOUR OWN COMMAND STRINGS
  1100.  
  1101. The parsing functions are normally examining the command line
  1102. to look for arguments to act on. However, you can equally well
  1103. use the routines to parse normal strings. This can be useful
  1104. if you have collected information from the user from a string
  1105. gadget for example, and now want to examine that string.
  1106.  
  1107. What you have to do is to prepare the CSource structure in
  1108. the RDArgs structure with the command line you want to parse:
  1109.  
  1110.   1. Give the "CS_Buffer" field a pointer to the string that
  1111.      you want to examine (parse).
  1112.  
  1113.   2. Set the lenght of the string in the "CS_Length" filed.
  1114.  
  1115.   3. Set the current character position to zero in the
  1116.      "CS_CurChr" filed.
  1117.  
  1118. Here is an example:
  1119.  
  1120.   /* Here is our own command line we want to parse: */
  1121.   UBYTE *my_command_line = "Bird.snd Volume=35 Filter\n";
  1122.  
  1123.   - - -
  1124.   /* Allocate a RDArgs structure etc... */
  1125.   - - -
  1126.  
  1127.   /* 1. Give the RDArgs structure our own command line: */
  1128.   my_rdargs->RDA_Source.CS_Buffer = my_command_line;
  1129.  
  1130.   /* 2. Set the length of the command line: */
  1131.   my_rdargs->RDA_Source.CS_Length = strlen( my_command_line );
  1132.  
  1133.   /* 3. Set the current character position to zero: */
  1134.   my_rdargs->RDA_Source.CS_CurChr = 0;
  1135.  
  1136.   - - -
  1137.   /* Parse the command line, examine the */
  1138.   /* results, and so on...               */
  1139.  
  1140.